package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/urfave/cli"
)

type UserInfo struct {
	IsLogin  bool   `json:"is_login"`
	Username string `json:"username"`
	//AccessToken string
}

// SignIn 执行签到请求
func SignIn(c *cli.Context) error {
	username := c.String("username")
	password := c.String("password")
	fmt.Println(username, password)
	userInfo := UserInfo{
		IsLogin:  true,
		Username: username,
	}

	// 构建 POST 请求体
	body := fmt.Sprintf("username=%s&password=%s", username, password)

	client := &http.Client{}
	req, err := http.NewRequest("POST", "http://www.1050qm.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0", strings.NewReader(body))
	if err != nil {
		return fmt.Errorf("Failed to create request: %v", err)
	}

	// 添加请求头部
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("Failed to sign-in: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Failed to sign-in. Status: %s", resp.Status)
	}

	err = SaveUserInfo(userInfo)
	if err != nil {
		log.Printf("SaveUserInfo(userInfo) failed,err=%v\n", err)
		LogToDisk("SaveUserInfo(userInfo) failed,err=%v", err)
		return err
	}
	log.Println(username + " Signed in to app")
	LogToDisk(username+" Signed in to app", nil)
	return nil
}

func SaveUserInfo(userInfo UserInfo) error {
	data, err := json.Marshal(userInfo)
	if err != nil {
		log.Printf("json.Marshal(userInfo) failed,err=%v\n", err)
		LogToDisk("json.Marshal(userInfo) failed,err=%v", err)
		return err
	}
	err = ioutil.WriteFile("userInfo.json", data, 0644)
	if err != nil {
		log.Printf("ioutil.WriteFile(\"userInfo.json\", data, 0644) failed,err=%v\n", err)
		LogToDisk("ioutil.WriteFile(\"userInfo.json\", data, 0644) failed,err=%v", err)
		return err
	}
	return nil
}

// ApplyTaskFunction 申请每日任务
func ApplyTaskFunction(c *cli.Context) error {
	//需要先去判断是否已经登录
	userInfo, err := loadUserInfo()
	if err != nil || !userInfo.IsLogin {
		log.Println("you don't login,please login first")
		return err
	}

	client := &http.Client{}
	req, err := http.NewRequest("GET", "http://www.1000qm.vip/home.php?mod=task&do=apply&id=1", nil)
	if err != nil {
		return fmt.Errorf("Failed to create request: %v", err)
	}

	//req.Header.Set("Authorization", "Bearer "+userInfo.AccessToken)

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("Failed to apply for task: %v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Failed to apply for task. Status: %s", resp.Status)
	}

	LogToDisk(userInfo.Username+" Applied for daily task...", nil)
	log.Println(userInfo.Username + " Applied for daily task...")
	return nil
}

func loadUserInfo() (UserInfo, error) {
	userInfo := UserInfo{}
	file, err := os.Open("userInfo.json")
	if err != nil {
		log.Printf("os.Open(\"userInfo.json\") failed,err=%v\n", err)
		LogToDisk("os.Open(\"userInfo.json\") failed,err=%v", err)
		return userInfo, err
	}
	defer file.Close()
	err = json.NewDecoder(file).Decode(&userInfo)
	if err != nil {
		log.Printf("json.NewDecoder(file).Decode(&userInfo) failed,err=%v\n", err)
		LogToDisk("json.NewDecoder(file).Decode(&userInfo) failed,err=%v", err)
		return userInfo, err
	}
	return userInfo, nil
}

// LogToDisk 将日志信息记录到本地磁盘
func LogToDisk(logMsg string, err error) error {
	logFile, err := os.OpenFile("forum_sign-in_log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("failed to open log file: %v", err)
	}
	defer logFile.Close()

	// 添加时间戳和消息
	logEntry := fmt.Sprintf("%s: %s\n", time.Now().Format("2006-01-02 15:04:05"), logMsg)
	if _, err := logFile.WriteString(logEntry); err != nil {
		return fmt.Errorf("failed to write to log file: %v", err)
	}
	return nil
}

func main() {
	app := &cli.App{
		Name:  "Forum Sign-In",
		Usage: "A CLI application for signing in to forums and applying for daily tasks.",
		Commands: []cli.Command{
			{
				Name:    "sign-in",
				Usage:   "Sign in to the forum",
				Aliases: []string{"s"},
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:     "username",
						Usage:    "The username value for sign-in",
						Required: true,
					},
					&cli.StringFlag{
						Name:     "password",
						Usage:    "The password value for sign-in",
						Required: true,
					},
				},
				Action: SignIn,
			},
			{
				Name:    "apply-task",
				Usage:   "Apply for the daily task",
				Aliases: []string{"at"},
				Action:  ApplyTaskFunction,
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		fmt.Printf("Error running app: %v\n", err)
	}
}
